#include "gRtsp.h"




int  grtsp_paraseUrl(g_rtspHeader* header,g_rtspAuthInfo *authinfo,char* url){
// rtsp://username:password@<ipaddress>/<videotype>/ch<number>/<streamtype>----带有鉴权字段
// rtsp_url = (“rtsp:”| “rtspu:”) “//” host [“:”port”] /[abs_path]/content_name
    int parse_len=0;   
    if(strstr(url,"rtspu://") != NULL){
        parse_len=8;
    }else if(strstr(url,"rtsp://") != NULL){
        parse_len=7;
    }else{
        parse_len=0;
        LOG("url is no invalid\n");
        return -1;
    }
    char * auth=strstr(url+ parse_len,"@");
    if(auth == NULL){
        LOG("not need auth");
    }else{
        char userpwd[G_LEN_256]={'\0'};
        strncpy(userpwd,url+ parse_len, auth-(url+ parse_len));
        char* split = strstr(userpwd,":");
        snprintf(authinfo->user,1+(split-userpwd),"%s",userpwd);
        sprintf(authinfo->pwd,"%s",split+1);
        parse_len = 1+auth-url;
    }
    char *ip=strstr(url+parse_len,"/");
    if(ip == NULL){
        if(strstr(url+parse_len,":")==NULL){
            sprintf(header->ip,"%s",url+parse_len);
            header->port=554;
        }else{
            char* p = strstr(url+parse_len,":");
            snprintf(header->ip,(p-(url+parse_len)),"%s",(url+parse_len));
            header->port = atoi(p+1);
            parse_len = ip-url;
        }
        return 0;
    }else{
        char host[G_LEN_256]={'\0'};
        strncpy(host,url+ parse_len, ip-(url+ parse_len));
        if(strstr(host,":")==NULL){
            sprintf(header->ip,"%s",host);
            header->port=554;
        }else{
            char* p = strstr(host,":");
            snprintf(header->ip,(p-host),"%s",host);
            header->port = atoi(p+1);
            parse_len = ip-url;
        }    
    }
    sprintf(header->path,"%s",url+parse_len);
    return 0;
}


int grtsp_createTcpSocket(g_rtspRequest request){
    struct timeval timeo = {G_REQUSTE_TIMEOUT_S, 0};
	int client_fd = socket(AF_INET,SOCK_STREAM,0);///创建套接字
	if(client_fd <0){
		LOG("创建 rtsp socket fail:result:%d\n",errno);
		return -1;
	}
	struct sockaddr_in server;
	memset(&server,0,sizeof(server));
	server.sin_family = AF_INET;
	server.sin_port = htons(request.header.port);
	server.sin_addr.s_addr = htonl(INADDR_ANY);
	server.sin_addr.s_addr = inet_addr(request.header.ip); 

    setsockopt(client_fd, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeo, sizeof(timeo));
    if (connect(client_fd,(struct sockaddr *)&server,sizeof(struct sockaddr_in)) <0){
		LOG("connect %s fail in %d seconds",request.header.ip,G_REQUSTE_TIMEOUT_S);
        return -1;
	}
    return client_fd;
}


int  grtsp_sendOptions(g_rtspRequest * request){
// C-->S
// OPTIONS rtsp://192.168.113.111:554 RTSP/1.0
// CSeq: 2
// User-Agent: LibVLC/3.0.10 (LIVE555 Streaming Media v2016.11.28)

    char option[G_LEN_1024]={"\0"};
    if(strlen(request->header.path)>2){
        sprintf(option,"OPTIONS rtsp://%s:%d/%s RTSP/1.0\r\nCSeq:%d\r\nUser-Agent:GRTSP/1.0\r\n\r\n",
        request->header.ip,request->header.port,request->header.path,++(request->cseq));
    }else{
        sprintf(option,"OPTIONS rtsp://%s:%d RTSP/1.0\r\nCSeq:%d\r\nUser-Agent:GRTSP/1.0\r\n\r\n",
        request->header.ip,request->header.port,++(request->cseq));    
    }
    int ret =-1;
    ret = send(request->rtsp_sock,option,strlen(option),0);
    if(ret >= 0){
        memset(option,0,sizeof(option));
        recv(request->rtsp_sock,option,sizeof(option),0);
        char *r=strtok(option,"\r\n");
        int line_num=0;
        int getCseq=0;
        while(r != NULL){
            if(line_num==0){
                char *s,*e;
                s = strstr(r," ");
                if(s != NULL){
                    e = strstr(s+1," ");
                    if(e != NULL){
                        char tmp[G_LEN_32];  
                        snprintf(tmp,1+e-s,"%s",s);
                        request->rspCode =atoi(tmp);
                    }
                }
            }
            else if(request->rspCode == 200 && line_num==1){
                getCseq = atoi(r+5);
            }
            else if(request->rspCode== 200 && line_num==2){
                sprintf(request->srv_supCmdList,"%s",r+7);
            }  
            line_num++;
            r=strtok(NULL,"\r\n");
        }
    }else{
        LOG("Send to %s OPTIONS REQ Fail",request->header.ip);
        return -1;
    }
    return 0;
}


int  grtsp_sendDescribe(g_rtspRequest * request){
// C-->S
// DESCRIBE rtsp://192.168.113.111:554 RTSP/1.0
// CSeq: 3
// User-Agent: LibVLC/3.0.10 (LIVE555 Streaming Media v2016.11.28)
// Accept: application/sdp
    char option[G_LEN_1024]={"\0"};
    if(strlen(request->header.path)>2){
        sprintf(option,"DESCRIBE rtsp://%s:%d/%s RTSP/1.0\r\nCSeq:%d\r\nUser-Agent:GRTSP/1.0\r\nAccept: application/sdp\r\n\r\n",
        request->header.ip,request->header.port,request->header.path,++(request->cseq));
    }else{
        sprintf(option,"DESCRIBE rtsp://%s:%d RTSP/1.0\r\nCSeq:%d\r\nUser-Agent:GRTSP/1.0\r\nAccept: application/sdp\r\n\r\n",
        request->header.ip,request->header.port,++(request->cseq));    
    }
    int ret =-1;
    ret = send(request->rtsp_sock,option,strlen(option),0);
    if(ret >= 0){
        memset(option,0,sizeof(option));
        recv(request->rtsp_sock,option,sizeof(option),0);
        char *r=strtok(option,"\r\n");
        int line_num=0;
        int getCseq=0;
        while(r != NULL){
            if(line_num==0){
                char *s,*e;
                s = strstr(r," ");
                if(s != NULL){
                    e = strstr(s+1," ");
                    if(e != NULL){
                        char tmp[G_LEN_32];  
                        snprintf(tmp,1+e-s,"%s",s);
                        request->rspCode =atoi(tmp);
                    }
                }
            }
            else if(request->rspCode == 200 && line_num==1){
                getCseq = atoi(r+5);
            }
            else if(request->rspCode== 200 && line_num==2){
                LOG("%s",r);
                sprintf(request->srv_supCmdList,"%s",r+7);
            }  
            line_num++;
            r=strtok(NULL,"\r\n");
        }
    }else{
        LOG("Send to %s OPTIONS REQ Fail",request->header.ip);
        return -1;
    }
    return 0;
}

